/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package aviso.controller;

import aviso.entity.AdvType;
import aviso.entity.Advert;
import aviso.entity.Area;
import aviso.entity.AreaType;
import aviso.entity.Bounds;
import aviso.entity.Building;
import aviso.entity.UserName;
import aviso.facade.AreaFacade;
import aviso.facade.AdvertFacade;
import aviso.facade.AreaTypeFacade;
import aviso.facade.DataGenFacade;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;


/**
 *
 * @author avgusti
 */
@ManagedBean(name = "addressLookup")
@ViewScoped
public class AdderssLookup implements Serializable {

    private String address;
    private Long id;
    private int genCount=100;
    @EJB
    DataGenFacade dataGenFacade;
    @EJB
    private AreaTypeFacade areaTypeFacade;
    @EJB
    private AreaFacade areaFacade;
    @EJB
    private AdvertFacade advertFacade;
    @ManagedProperty(value = "#{frontController.user}")
    private UserName userName;
    @ManagedProperty(value = "#{frontController}")
    private FrontController fc;

    public UserName getUserName() {
        return userName;
    }

    public void setUserName(UserName userName) {
        this.userName = userName;
    }

    public FrontController getFc() {
        return fc;
    }

    public void setFc(FrontController fc) {
        this.fc = fc;
    }
    private double lat, lng;
    private int zoom;
    private Bounds bounds = new Bounds();

    ///////////////////////////////////////////////////////////////////////////
    //DUMP function for map update
    public void submit() {
    }

    public int getZoom() {
        return zoom;
    }

    public void setZoom(int zoom) {
        this.zoom = zoom;
    }

    public Bounds getBounds() {
        return bounds;
    }

    public void setBounds(Bounds bounds) {
        this.bounds = bounds;
    }

    public double getLat() {
        return lat;
    }

    public void setLat(double lat) {
        this.lat = lat;
    }

    public double getLng() {
        return lng;
    }

    public void setLng(double lng) {
        this.lng = lng;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public int getGenCount() {
        return genCount;
    }

    public void setGenCount(int genCount) {
        this.genCount = genCount;
    }

    public void updateAdvertLocation() {
        Advert a = advertFacade.find(id);
        a.setLat(lat);
        a.setLng(lng);
        advertFacade.edit(a);
        Logger.getAnonymousLogger().log(Level.INFO, "Adv id={0} [{1}x{2}]", new Object[]{id, lat, lng});
    }

public List<String> complete(String adr) {
        setAddress(adr);
        listStreets(adr);
        FacesContext fc = FacesContext.getCurrentInstance();
        List<String> cresult = new ArrayList<String>();
        List<Area> areas = areaFacade.lookUpByTypeId(adr.toLowerCase() + "%", Long.valueOf(3));
        for (Area area : areas) {
            cresult.add(printArea(area, ""));
        }
        return cresult;
    }

    public List<String> getStreets() {
        return result;
    }
    private List<String> result;
    private String request = "";

    private List<String> listStreets(String city) {
        int count = 0;
        if (city != null && request != null && !request.equals(city)) {
            request = city;
            result = new ArrayList<String>();
            //TODO cnage to ID
            Area a = null;
            List<Area> byName = areaFacade.getByName(city);
            if (!byName.isEmpty()) {
                a = byName.get(0);
                List<Area> al = areaFacade.lookUpChildren(a);
                for (Area area : al) {
                    //if(count>10) break;
                    result.add(printArea(area, ""));
                    count++;
                }
            }
        }
        return result;
    }

    public List<Area> parseAddress(String adr) {
        String parts[] = adr.split(",");
        List<Area> lparts = new ArrayList();
        TreeMap<Long, Area> tmp = new TreeMap();
        for (String s : parts) {
            List<Area> lpart = areaFacade.getByName(s);
            if (lpart != null && lpart.size() > 0) {
                lparts.addAll(lpart);
            }
        }
        int max = 0;
        Area mach = null;
        for (Area a : lparts) {
            int level = 0;
            Area tmpa = a;
            while (lparts.contains(tmpa.getParent())) {
                level++;
                tmpa = tmpa.getParent();
            }
            tmp.put(new Long(level), a);
            if (max < level) {
                max = level;
                mach = a;
            }
        }
        return new ArrayList<Area>(tmp.values());

    }

    public String printArea(Area area, String i) {
        String fullAd = "";
        if (area != null) {
            fullAd = area.getName();
            Area pa = area.getParent();
            if (area.getType().getId() == 3) {
                fullAd += " " + i;
            }
            while (pa != null) {
                fullAd += ", " + pa.getName();
                pa = pa.getParent();
            }
        }
        return fullAd;
    }
    private Random r = new Random();
    private int rflors_apt[] = {5, 6, 9, 9, 12, 16, 16};
    private int rflors_build[] = {1, 2, 2, 3};
    private AdvType rtype[] = {AdvType.APPARTMENT, AdvType.APPARTMENT, AdvType.APPARTMENT, AdvType.APPARTMENT, AdvType.APPARTMENT, AdvType.APPARTMENT, AdvType.BUILDING};
    private int rrooms_apt[] = {1, 1, 2, 2, 3, 1, 2, 2, 3, 4, 5};
    private int rrooms_build[] = {1, 2, 3, 3, 3, 4, 5};
    private int rkitchen[] = {6, 7, 7, 8, 8, 8, 8, 10, 12};
    private int rbalkony[] = {0, 2, 3, 3, 4, 4, 5, 6, 6, 12};
    private int rlivingl[] = {28, 40, 62, 80, 120};
    private int rlivingb[] = {10, 15, 20, 30, 60};
    private int rpricel[] = {60, 80, 100, 150, 200};
    private int rpriceb[] = {30, 40, 50, 100, 200};

    private int getRnd(int array[]) {
        return array[r.nextInt(array.length)];
    }

    private int getValByRndinBounds(int idx, int valsl[], int valsb[]) {
        return valsl[idx] + r.nextInt(valsb[idx]);
    }

    public void initStreets() {
        dataGenFacade.initAreas();
    }

    public void clearAreas() {


        dataGenFacade.deleteAreas();
    }
    
    public void clearAdvs() {


        dataGenFacade.deleteAdvs();
    }
    
    public void genAdvs() {

        Area a = areaFacade.getByName("Киев").get(0);
        List<Area> al = areaFacade.lookUpChildren(a);
        //data for generator porbability
//        for (int i = 0; i < 10000; i++){
//            Building b=new Building();
//            
//        }
        for (int i = 0; i < genCount; i++) {

            Advert adv = new Advert();
            a = al.get(r.nextInt(al.size()));

            adv.setAddress(printArea(a, "" + r.nextInt(20)));
            adv.setLat(a.getLat());
            adv.setLng(a.getLng());
            adv.setType(rtype[r.nextInt(rtype.length)]);
            if (adv.getType() == AdvType.APPARTMENT) {
                adv.setFloors(getRnd(rflors_apt));
                adv.setFloor(r.nextInt(adv.getFloors()) + 1);
                adv.setRoom_count(getRnd(rrooms_apt));
            } else {
                adv.setFloors(getRnd(rflors_build));
                adv.setFloor(0);
                adv.setRoom_count(getRnd(rrooms_apt));
            }

            adv.setKitchen_sqr(getRnd(rkitchen));
            adv.setBalkony_sqr(getRnd(rbalkony));
            adv.setTotal_sqr(getValByRndinBounds(adv.getRoom_count() - 1, rlivingl, rlivingb));
            adv.setLiving_sqr(adv.getTotal_sqr() - adv.getKitchen_sqr() - adv.getBalkony_sqr());

            adv.setPrice(getValByRndinBounds(adv.getRoom_count() - 1, rpricel, rpriceb));

            advertFacade.create(adv);
            adv.setUser(userName);
            advertFacade.edit(adv);


        }
    }
}
